import { createLazyFileRoute } from '@tanstack/react-router'
import * as React from 'react'
import { useRef, useState } from 'react'
import { Button, Input, Select, SelectContent, SelectItem, SelectScrollDownButton, SelectScrollUpButton, SelectTrigger, SelectValue } from 'v1-components'
import { useAtom, useAtomValue } from 'jotai'
import { RocketIcon } from 'lucide-react'
import { type ISearchInput, LLMModel } from '../../../shared/types'
import { CoreRepl, MiniPreviewRepl } from '../components/Repl.lazy'
import { questionAtom, selectedVersionAtom } from '@/store/question'
import { V1NavigationMenu } from '@/components/V1NavigationMenu'

function ResultPage() {
  const firstSearch = useAtomValue(questionAtom)
  const [questions, setQuestions] = useState<ISearchInput[]>(firstSearch ? [firstSearch] : [])
  const [codes, setCodes] = useState<string[]>([])
  const [selectedVersion, setSelectedVersion] = useAtom(selectedVersionAtom)

  const [model, setModel] = useState<LLMModel>(firstSearch?.model ?? LLMModel.GPT4)

  const additionalInputRef = useRef<HTMLInputElement>(null)

  const submit = () => {
    const input = additionalInputRef.current?.value?.trim() ?? ''
    if (input !== '') {
      setSelectedVersion(questions.length)
      setQuestions([...questions, { type: 'text', value: input, previousCode: codes[selectedVersion], model }])
      additionalInputRef.current!.value = ''
    }
  }

  const onEnter: React.DOMAttributes<HTMLInputElement>['onKeyPress'] = (e) => {
    if (e.code === 'Enter')
      submit()
  }

  return (
    <main className="vx-dev-wrapper relative flex flex-col h-[100vh]">
      <V1NavigationMenu currentSearchInput={questions[selectedVersion]} />
      <div className="h-[80vh] flex-grow flex flex-row">
        <div className="h-full w-[280px] bg-[#f3f3f3] block overflow-auto border-y-[20px] border-[#f3f3f3] border-solid">
          <React.Suspense fallback={<Pending />}>
            <MiniPreviews codes={codes} questions={questions} />
          </React.Suspense>
        </div>
        <div className="h-full w-[100vw] flex-1 border-y-[20px] border-r-[20px] border-l-[10px] border-[#f3f3f3]">
          <React.Suspense fallback={<Pending />}>
            <CoreRepls
              questions={questions}
              codes={codes}
              setCodes={setCodes}
            />
          </React.Suspense>

        </div>
      </div>
      <div className="h-20 flex flex-col justify-center items-center">
        <div className="w-[900px] flex rounded-[10px] border-[1px] p-1">
          <Select value={model} onValueChange={setModel}>
            <SelectTrigger className="w-[150px] border-none focus-visible:ring-0 focus:ring-0">
              <SelectValue />
            </SelectTrigger>

            <SelectContent>
              <SelectScrollUpButton />

              <SelectItem value={LLMModel.GPT4}>{LLMModel.GPT4}</SelectItem>
              <SelectItem value={LLMModel.Claude3}>{LLMModel.Claude3}</SelectItem>

              <SelectScrollDownButton />
            </SelectContent>
          </Select>
          <Input
            className="focus-visible:ring-0 border-none mx-2"
            id="website-description-input"
            placeholder="What do you want to modify? e.g. Make the title larger."
            ref={additionalInputRef}
            onKeyPress={onEnter}
          />
          <Button
            className="text-xl p-2 bg-transparent hover:bg-[#88888820] text-[#303030] focus-visible:ring-0"
            onClick={() => submit()}
          >
            <RocketIcon />
          </Button>
        </div>
      </div>
    </main>
  )
}

function MiniPreviews({ codes, questions }: {
  codes: string[]
  questions: ISearchInput[]
}) {
  const [selectedVersion, setSelectedVersion] = useAtom(selectedVersionAtom)

  return (
    <section>
      <h1 className="mx-[24px] mb-4 font-bold">History</h1>
      {
      codes.map((code, index) => (
        <div className="flex flex-col items-center mb-[20px] mx-[20px]" key={index.toString()}>
          <div
            className={`w-[240px] h-[180px] bg-white overflow-hidden rounded-2xl cursor-pointer border-solid border-4 hover:border-[#0070c1] ${index === selectedVersion ? 'border-[#a3a3a3]' : 'border-[#e3e3e3]'}`}
            onClick={() => setSelectedVersion(index)}
          >
            <MiniPreviewRepl code={code}></MiniPreviewRepl>
          </div>
          <span className="mt-2 bg-[#d3d3d3] w-[200px] rounded-2xl text-center text-[12px] px-4 text-nowrap overflow-hidden overflow-ellipsis h-6 leading-6 cursor-default select-none">
            {questions[index].type === 'image_url' ? `[${questions[index].fileName}]` : questions[index].value}
          </span>
        </div>
      ))
    }
    </section>
  )
}
function CoreRepls({ questions, codes, setCodes }: {
  questions: ISearchInput[]
  codes: string[]
  setCodes: React.Dispatch<React.SetStateAction<string[]>>
}) {
  const selectedVersion = useAtomValue(selectedVersionAtom)

  return questions.map((question, index) => (
    <CoreRepl
      hidden={index !== selectedVersion}
      key={index.toString()}
      onCodeChange={(c) => {
        const result = codes.slice(0)
        result[index] = c
        setCodes(result)
      }}
      searchInput={question}
    />
  ))
}

function Pending() {
  return (
    <div className="h-full w-ful p-6">
      <div role="status" className="max-w-[600px] animate-pulse">
        <div className="h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 w-48 mb-4"></div>
        <div className="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[600px] mb-2.5"></div>
        <div className="h-2 bg-gray-200 rounded-full dark:bg-gray-700 mb-2.5"></div>
        <div className="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[580px] mb-2.5"></div>
        <div className="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[560px] mb-2.5"></div>
        <div className="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[600px] mb-8"></div>
        <div className="h-2.5 bg-gray-200 rounded-full dark:bg-gray-700 w-48 mb-4"></div>
        <div className="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[600px] mb-2.5"></div>
        <div className="h-2 bg-gray-200 rounded-full dark:bg-gray-700 mb-2.5"></div>
        <div className="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[580px] mb-2.5"></div>
        <div className="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[560px] mb-2.5"></div>
        <div className="h-2 bg-gray-200 rounded-full dark:bg-gray-700 max-w-[600px]"></div>
      </div>
    </div>
  )
}
export const Route = createLazyFileRoute('/result')({
  component: ResultPage,
  pendingComponent: Pending,
})
